from odoo import fields, models, api
from odoo.exceptions import UserError, ValidationError
from ...functions.common import is_continuous
from ..setting.rp_weight_gradient_template import WEIGHT_TYPE
from .rp_courier_mail_route import EXPRESS_CATEGORY


class RPCourierCostTemplateValueAddedLine(models.Model):
    _name = 'rp.courier.cost.template.value.added.line'
    _description = '承运商成本价增值明细'
    _sql_constraints = [('unique_code', 'UNIQUE(code)', '编码不允许重复')]
    _rec_name = 'code'
    _order = 'code ASC'

    rp_courier_cost_template_id = fields.Many2one(string='关联主表', comodel_name='rp.courier.cost.template', required=True, ondelete='cascade')
    code = fields.Char(string='编码', default='New', readonly=True, copy=False, index=True)

    courier_id = fields.Many2one(string='承运商', comodel_name='rp.courier', related='rp_courier_cost_template_id.courier_id', store=True)
    courier_value_added_id = fields.Many2one(string='增值服务', comodel_name='rp.value.added.service')
    courier_value_added_category = fields.Selection(string='增值服务大类', related='courier_value_added_id.category')

    cost_price = fields.Monetary(string='成本价', default=0)
    currency_id = fields.Many2one(string='货币单位', comodel_name='res.currency', default=lambda self: self.env.company.currency_id)
    active_flag = fields.Boolean(string='有效', related='rp_courier_cost_template_id.active_flag', store=True)

    @api.model_create_multi
    def create(self, vals_list):
        for vals in vals_list:
            rp_courier_cost_template_id = vals.get('rp_courier_cost_template_id')
            prefix = self.env['rp.courier.cost.template'].search([('id', '=', rp_courier_cost_template_id)]).courier_id.code
            code = self.env['rp.sequence.code'].explore_sequence(model=self._name, prefix=prefix, key='VL', padding=4)
            vals.update({'code': code})
        result = super(RPCourierCostTemplateValueAddedLine, self).create(vals_list)
        return result


class RPCourierCostTemplateLine(models.Model):
    _name = 'rp.courier.cost.template.mail.route.line'
    _description = '承运商成本价邮路明细'
    _rec_name = 'code'
    _order = 'code ASC'
    _sql_constraints = [('unique_code', 'UNIQUE(code)', '编码不允许重复')]

    def _default_get_kg(self):
        kg = self.env['uom.uom'].search([('name', '=', 'kg')])
        return kg.id if kg else False

    rp_courier_cost_template_id = fields.Many2one(string='关联主表', comodel_name='rp.courier.cost.template', ondelete='cascade')
    code = fields.Char(string='编码', default='New', readonly=True, copy=False, index=True)

    courier_id = fields.Many2one(string='承运商', comodel_name='rp.courier', related='rp_courier_cost_template_id.courier_id', store=True)
    courier_mail_route_id = fields.Many2one(string='承运商邮路', comodel_name='rp.courier.mail.route')

    aging_available_ids = fields.Many2many(string='可用时效', comodel_name='rp.aging', related='courier_mail_route_id.aging_ids')
    aging_id = fields.Many2one(string='时效', comodel_name='rp.aging', required=True)

    ship_from_country_group_available_ids = fields.Many2many(string='可用启运地', comodel_name='res.country.group', related='courier_mail_route_id.ship_from_country_group_ids')
    ship_to_country_group_available_ids = fields.Many2many(string='可用目的地', comodel_name='res.country.group', related='courier_mail_route_id.ship_to_country_group_ids')
    same_city_flag = fields.Boolean(string='同城', related='courier_mail_route_id.same_city_flag', store=True)
    same_province_flag = fields.Boolean(string='同省', related='courier_mail_route_id.same_province_flag', store=True)
    express_category = fields.Selection(string='发件类型', selection=EXPRESS_CATEGORY, related='courier_mail_route_id.express_category')
    ship_from_country_group_ids = fields.Many2many(string='启运地', comodel_name='res.country.group', required=True, relation='rp_cost_line_ship_from_and_country_groups_rel', column1='cost_line_id', column2='country_group_id')
    ship_to_country_group_ids = fields.Many2many(string='目的地', comodel_name='res.country.group', required=True, relation='rp_cost_line_ship_to_and_country_groups_rel', column1='cost_line_id', column2='country_group_id')

    weight_gradient_type = fields.Selection(string='重量梯度类型', selection=WEIGHT_TYPE, default=WEIGHT_TYPE[0][0], required=True)
    weight_gradient_template_id = fields.Many2one(string='重量梯度模板', comodel_name='rp.weight.gradient.template', domain="[('type','=',weight_gradient_type)]")
    courier_cost_template_line_ids = fields.One2many(string='关联重量明细', comodel_name='rp.courier.cost.template.weight.line', inverse_name='courier_cost_template_weight_line_id')
    inf = fields.Float(string='下确界', compute='_depends_compute_bounds', store=True, digits=(5, 2), default=0)
    sup = fields.Float(string='上确界', compute='_depends_compute_bounds', store=True, digits=(5, 2), default=0)

    active_flag = fields.Boolean(string='有效', related='rp_courier_cost_template_id.active_flag', store=True)

    @api.onchange('courier_mail_route_id')
    def _onchange_courier_mail_route_id(self):
        if self.courier_mail_route_id:
            self.update({'aging_id': False,
                         'ship_from_country_group_ids': False,
                         'ship_to_country_group_ids': False})

    @api.onchange('weight_gradient_type')
    def _onchange_weight_gradient_type(self):
        if self.weight_gradient_type:
            self.update({'weight_gradient_template_id': False})

    @api.onchange('ship_from_country_group_ids', 'ship_to_country_group_ids')
    def _onchange_from_to_groups(self):
        if self.same_province_flag or self.same_city_flag:
            # 只有启运地，无目的地
            if len(self.ship_from_country_group_ids.ids) > 0 and len(self.ship_to_country_group_ids.ids) == 0:
                self.update({'ship_to_country_group_ids': [(6, 0, self.ship_from_country_group_ids.ids)]})
            # 只有目的地，无启运地
            if len(self.ship_to_country_group_ids.ids) > 0 and len(self.ship_from_country_group_ids.ids) == 0:
                self.update({'ship_from_country_group_ids': [(6, 0, self.ship_to_country_group_ids.ids)]})
            # 启运地和目的地均存在
            if len(self.ship_from_country_group_ids.ids) > 0 and len(self.ship_to_country_group_ids.ids) > 0:
                self.update({'ship_to_country_group_ids': self.ship_from_country_group_ids.ids})

    @api.depends('courier_cost_template_line_ids.min_weight', 'courier_cost_template_line_ids.max_weight')
    def _depends_compute_bounds(self):
        """ 计算上确界和下确界 """
        for s in self:
            if s.courier_cost_template_line_ids:
                intervals = []
                for wgt in s.courier_cost_template_line_ids:
                    intervals.append((wgt.min_weight, wgt.max_weight))
                flag, inf, sup = is_continuous(intervals)
                if not flag:
                    raise UserError('所配置的重量梯度非连续')
                s.write({'inf': inf, 'sup': sup})

    @api.model_create_multi
    def create(self, vals_list):
        for vals in vals_list:
            rp_courier_cost_template_id = vals.get('rp_courier_cost_template_id')
            prefix = self.env['rp.courier.cost.template'].search([('id', '=', rp_courier_cost_template_id)]).courier_id.code
            code = self.env['rp.sequence.code'].explore_sequence(model=self._name, prefix=prefix, key='CS', padding=5)
            vals.update({'code': code})
        result = super(RPCourierCostTemplateLine, self).create(vals_list)
        return result

    @api.onchange('weight_gradient_template_id')
    def _fulfill_weight_line(self):
        if self.weight_gradient_template_id:
            create_list = []
            for wgt in self.weight_gradient_template_id.weight_gradient_template_ids:
                values = {'min_weight': wgt.min_weight,
                          'max_weight': wgt.max_weight,
                          'carry_value': wgt.carry_value,
                          'uom_id': wgt.uom_id.id}
                create_list.append((0, 0, values))
            self.update({'courier_cost_template_line_ids': [(5, 0, 0)]})
            self.update({'courier_cost_template_line_ids': create_list})

    def action_for_increase_tax_value(self):
        """ 增加税值 """
        if self.courier_cost_template_line_ids:
            for cct in self.courier_cost_template_line_ids:
                cct.start_price = cct.start_price * (1 + 0.21)
                cct.carry_price = cct.carry_price * (1 + 0.21)

    def action_for_decrease_tax_value(self):
        """ 减少税值 """
        if self.courier_cost_template_line_ids:
            for cct in self.courier_cost_template_line_ids:
                cct.start_price = cct.start_price / (1 + 0.21)
                cct.carry_price = cct.carry_price / (1 + 0.21)


class RPCourierCostTemplateWeightLine(models.Model):
    _name = 'rp.courier.cost.template.weight.line'
    _description = '承运商成本价重量明细'

    def _default_get_kg(self):
        kg = self.env['uom.uom'].search([('name', '=', 'kg')])
        return kg.id if kg else False

    courier_cost_template_weight_line_id = fields.Many2one(string='关联主表', comodel_name='rp.courier.cost.template.mail.route.line', ondelete='cascade')

    min_weight = fields.Float(string='最小重量', digits=(5, 2), default=0, required=True)
    max_weight = fields.Float(string='最大重量', digits=(5, 2), default=0, required=True)
    uom_id = fields.Many2one(string='重量单位', comodel_name='uom.uom', default=_default_get_kg)

    carry_value = fields.Float(string='进位值', digits=(3, 2), default=0, required=True)

    start_price = fields.Float(string='首重价', digits=(5, 3), default=0, required=True)
    carry_price = fields.Float(string='进位价', digits=(5, 3), default=0)
    currency_id = fields.Many2one(string='货币单位', comodel_name='res.currency', default=lambda self: self.env.company.currency_id)
